package com.gbits.app.finance.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import com.gbits.app.finance.domain.Subject;
import com.gbits.app.finance.service.DefaultAbstractService;
import com.gbits.app.finance.service.SubjectService;

@Service("subjectService")
@Transactional
public class SubjectServiceImpl extends DefaultAbstractService<Subject>
		implements SubjectService {

	public List<Subject> getSubjectsByCode(String code, String orgCode) {
		
		Assert.notNull(code, "科目代码不能为空");
		Assert.notNull(orgCode, "机构代码不能为空");
		List<String> codes = this.getCodes(code);
		
		String hql = "from " + Subject.class.getName() + " e where e.orgCode=:orgCode and e.code in (%s)";
		Map<String, Object> parameter = new HashMap<String, Object>();
		parameter.put("orgCode", orgCode);
		// parameter.put("codes", StringUtils.collectionToDelimitedString(codes, ",", "'", "'"));
		
		List<Subject> list = this.getBaseDao().findByNamesParameter(String.format(hql, StringUtils.collectionToDelimitedString(codes, ",", "'", "'")), parameter);
		List<Subject> subjects = new ArrayList<Subject>();
		Map<String, Subject> smap = new HashMap<String, Subject>();
		for (Subject s : list) {
			smap.put(s.getCode(), s);
		}
		
		for (String c : codes) {
			Subject subject = smap.get(c);
			if (null != subject) {
				subjects.add(subject);
			}
		}
		
		return subjects;
	}

	private List<String> getCodes(String code) {
		List<String> list = new ArrayList<String>();
		String[] arr = StringUtils.split(code, ".");
		StringBuffer str = new StringBuffer();
		char[] chars = code.toCharArray();
		for (char c : code.toCharArray()) {
			if (c == '.') {
				list.add(str.toString());
			}
			str.append(c);
		}
		if (str.length() > 0) {
			list.add(str.toString());
		}
		return list;
	}

	public List<Subject> getSubjectsDetail(String code, String subjectName,
			String orgCode) {
		
		Assert.notNull(code, "科目代码不能为空");
		Assert.notNull(orgCode, "机构代码不能为空");
		Assert.notNull(subjectName, "科目名称不能为空");
		
		String hql = "from " + Subject.class.getName() + " e where e.orgCode=:orgCode and e.name =:name and e.code like :code";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orgCode", orgCode);
		map.put("code", code + "%");
		map.put("name", subjectName);
		List<Subject> list = this.getBaseDao().findByNamesParameter(hql, map);
		if (null == list || list.isEmpty()) {
			throw new RuntimeException("未找到匹配的科目[" + code + "/" + subjectName + "]");
		}
		
		if (list.size() > 1) {
			throw new RuntimeException("找到匹配的科目["+ code + "/" + subjectName + "]重复");
		}
		
		Subject subject = list.get(0);
		
		String pcode = this.getParentCode(subject.getCode());
		List<Subject> subjects = new ArrayList<Subject>();
		if (null != pcode) {
			subjects = this.getSubjectsByCode(pcode, orgCode);
		}
		subjects.add(subject);
		return subjects;
	}
	
	private String getParentCode(String code) {
		List<String> codes = this.getCodes(code);
		int index = codes.size() - 2;
		if (index >= 0) {
			return codes.get(index);
		}
		return null;
	}

	public List<Subject> getSubjectsByEmp(String orgCode) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orgCode", orgCode);
		map.put("name", "个人");
		String hql = "from " + Subject.class.getName() + " e where e.orgCode=:orgCode and e.name =:name and code like '2241%'";
		List<Subject> list = this.getBaseDao().findByNamesParameter(hql, map);
		if (null == list || list.isEmpty()) {
			throw new RuntimeException("未找到匹配的科目[员工科目][" + orgCode + "/" + "个人" + "]");
		}
		if (list.size() > 1) {
			throw new RuntimeException("找到匹配的科目[员工科目][" + orgCode + "/" + "个人" + "]重复");
		}
		
		Subject subject = list.get(0);
		String pcode = this.getParentCode(subject.getCode());
		list = this.getSubjectsByCode(pcode, orgCode);
		list.add(subject);
		return list;
	}
	
	public List<Subject> getSubjectsByCmpEmp(String orgCode) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orgCode", orgCode);
		map.put("name1", "其他");
		map.put("name2", "单位");
		String hql = "from " + Subject.class.getName() + " e where e.orgCode=:orgCode and (e.name =:name1 or e.name = :name2) and code like '2241%'";
		List<Subject> list = this.getBaseDao().findByNamesParameter(hql, map);
		if (null == list || list.isEmpty()) {
			throw new RuntimeException("未找到匹配的科目[公司科目][" + orgCode + "/" + "公司与员工相关" + "]");
		}
		if (list.size() > 1) {
			throw new RuntimeException("找到匹配的科目[公司科目][" + orgCode + "/" + "公司与员工相关" + "]重复");
		}
		
		Subject subject = list.get(0);
		String pcode = this.getParentCode(subject.getCode());
		list = this.getSubjectsByCode(pcode, orgCode);
		list.add(subject);
		return list;
	}
	
	public List<Subject> getSubjectsByBankNo(String bankNo, String orgCode) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orgCode", orgCode);
		map.put("name", "%" + bankNo.substring(bankNo.length() - 4));
		String hql = "from " + Subject.class.getName() + " e where e.orgCode=:orgCode and e.name like :name";
		List<Subject> list = this.getBaseDao().findByNamesParameter(hql, map);
		if (null == list || list.isEmpty()) {
			throw new RuntimeException("未找到匹配的科目[银行科目][" + orgCode + "/" + "银行" + "]");
		}
		if (list.size() > 1) {
			throw new RuntimeException("找到匹配的科目[银行科目][" + orgCode + "/" + "银行" + "]重复");
		}
		
		Subject subject = list.get(0);
		String pcode = this.getParentCode(subject.getCode());
		list = this.getSubjectsByCode(pcode, orgCode);
		list.add(subject);
		return list;
	}

	public Subject getCompanyByEmp(String orgCode, String cmpName) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orgCode", orgCode);
		map.put("name", "%" + cmpName);
		String hql = "from " + Subject.class.getName() + " e where e.orgCode=:orgCode and e.name like :name and code like '2241%'";
		List<Subject> list = this.getBaseDao().findByNamesParameter(hql, map);
		if (null == list || list.isEmpty()) {
			throw new RuntimeException("未找到匹配的公司[公司科目][" + orgCode + "/" + cmpName + "]");
		}
		if (list.size() > 1) {
			throw new RuntimeException("找到匹配的公司[公司科目][" + orgCode + "/" + cmpName + "]重复");
		}
		
		Subject subject = list.get(0);
		return subject;
	}

	public Subject getCompanyByBusiness(String orgCode, String cmpName) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orgCode", orgCode);
		map.put("name", "%" + cmpName);
		String hql = "from " + Subject.class.getName() + " e where e.orgCode=:orgCode and e.name like :name and code like '2202%'";
		List<Subject> list = this.getBaseDao().findByNamesParameter(hql, map);
		if (null == list || list.isEmpty()) {
			throw new RuntimeException("未找到匹配的公司[" + orgCode + "/" + cmpName + "]");
		}
		if (list.size() > 1) {
			throw new RuntimeException("找到匹配的公司[" + orgCode + "/" + cmpName + "]重复");
		}
		Subject subject = list.get(0);
		return subject;
	}

	public List<Subject> getSubjectsByCmp(String orgCode) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orgCode", orgCode);
		map.put("name", "应付账款");
		String hql = "from " + Subject.class.getName() + " e where e.orgCode=:orgCode and e.name =:name and code like '2202%'";
		List<Subject> list = this.getBaseDao().findByNamesParameter(hql, map);
		if (null == list || list.isEmpty()) {
			throw new RuntimeException("未找到匹配的科目[" + orgCode + "/" + "应付账款" + "]");
		}
		if (list.size() > 1) {
			throw new RuntimeException("找到匹配的科目[" + orgCode + "/" + "应付账款" + "]重复");
		}
		
		Subject subject = list.get(0);
		String pcode = this.getParentCode(subject.getCode());
		if (null == pcode) {
			return list;
		}
		list = this.getSubjectsByCode(pcode, orgCode);
		list.add(subject);
		return list;
	}
	
	
	
}
